package category

import (
	"context"
	"mall/common/excption"
	constans "mall/services/product/rpc/consts"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"

	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type InfoLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCategoryInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InfoLogic {
	return &InfoLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *InfoLogic) CategoryInfo(in *pb.CategoryInfoDTO) (*pb.CategoryInfoVO, error) {
	// 1.check request dto
	categoryMapper, categoryEntity, err := l.checkRequestDTO(in)
	if err != nil {
		return nil, err
	}
	// 2.query db
	vo := l.queryDB(in, categoryEntity, categoryMapper)
	// 3.return obj
	return vo, nil
}

func (l *InfoLogic) queryDB(in *pb.CategoryInfoDTO, categoryEntity *entity.CategoryEntity,
	categoryMapper *mapper.CategoryMapper) *pb.CategoryInfoVO {

	vo := &pb.CategoryInfoVO{}
	vo.CategoryId = categoryEntity.CategoryId
	vo.ShopId = categoryEntity.ShopId
	vo.ParentId = categoryEntity.ParentId
	vo.Name = categoryEntity.Name
	vo.Desc = categoryEntity.Desc
	vo.Path = categoryEntity.Path
	vo.Status = int32(categoryEntity.Status)
	vo.Icon = categoryEntity.Icon
	vo.ImgUrl = categoryEntity.ImgUrl
	vo.Level = int32(categoryEntity.Level)
	vo.Seq = int32(categoryEntity.Seq)
	// loop children arr
	l.getCategoryTreeList(categoryMapper, in.CategoryId, vo)
	return vo
}

func (l *InfoLogic) checkRequestDTO(in *pb.CategoryInfoDTO) (*mapper.CategoryMapper, *entity.CategoryEntity, error) {
	categoryMapper := mapper.NewCategoryMapper(l.ctx)
	categoryBO := bo.CategoryBO{CategoryId: in.CategoryId}
	categoryEntity, err := categoryMapper.SelectOneCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return nil, nil, err
	}
	if categoryEntity.CategoryId <= 0 {
		return nil, nil, excption.NewErrCode(constans.CategoryNotExistErr)
	}
	return categoryMapper, &categoryEntity, nil
}

func (l *InfoLogic) getCategoryTreeList(categoryMapper *mapper.CategoryMapper, categoryId int64, vo *pb.CategoryInfoVO) {
	categoryBO := bo.CategoryBO{ParentId: categoryId, NeStatus: constans.Delete}
	selectListCtx, err := categoryMapper.SelectListCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return
	}
	if len(selectListCtx) < 1 {
		return
	}
	var categoryArr []*pb.CategoryInfoVO
	for _, v := range selectListCtx {
		categoryVO := new(pb.CategoryInfoVO)
		categoryVO.CategoryId = v.CategoryId
		categoryVO.ShopId = v.ShopId
		categoryVO.ParentId = v.ParentId
		categoryVO.Name = v.Name
		categoryVO.Desc = v.Desc
		categoryVO.Path = v.Path
		categoryVO.Status = int32(v.Status)
		categoryVO.Icon = v.Icon
		categoryVO.ImgUrl = v.ImgUrl
		categoryVO.Level = int32(v.Level)
		categoryVO.Seq = int32(v.Seq)
		categoryArr = append(categoryArr, categoryVO)
		// 递归子节点
		l.getCategoryTreeList(categoryMapper, v.CategoryId, categoryVO)
		vo.ChildrenArr = categoryArr
	}

}
